/**
 * @file aodv.h
 * @brief AODV (Ad-hoc On-demand Distance Vector) 路由协议主头文件
 * 
 * 该文件定义了AODV协议的公共接口和核心功能函数声明。
 * AODV是一种适用于移动自组织网络(MANET)的按需距离矢量路由协议，
 * 主要特点包括：按需路由发现、无环路路由维护、支持移动性、低控制开销等。
 */
#ifndef AODV_H
#define AODV_H

#include "aodv_types.h"
#include <stddef.h>

/**
 * @brief 初始化AODV协议栈
 * 
 * 初始化AODV协议的各个组件，包括路由表、邻居表、定时器等，
 * 设置节点IP地址和配置参数。这是使用AODV协议的第一步。
 * 
 * @param my_ip 当前节点的IP地址
 * @param config 可选的AODV配置参数，如果为NULL则使用默认配置
 * @return 成功返回0，失败返回负值
 */
extern int aodv_init(uint32_t my_ip, const aodv_config_t *config);

/**
 * @brief 清理AODV协议栈资源
 * 
 * 释放AODV协议栈使用的所有资源，包括路由表、邻居表、定时器等，
 * 在程序结束前调用以避免资源泄漏。
 */
extern void aodv_cleanup(void);

/**
 * @brief 发送数据到指定目标IP
 * 
 * 尝试通过AODV协议将数据发送到指定的目标IP地址。如果路由存在，
 * 直接使用该路由发送数据；如果路由不存在，则发起路由发现过程。
 * 
 * @param dest_ip 目标IP地址
 * @param data 要发送的数据缓冲区指针
 * @param data_len 数据长度（字节）
 * @return 成功返回0，失败返回负值
 */
extern int aodv_send_data(uint32_t dest_ip, const void *data, size_t data_len);

/**
 * @brief 处理接收到的数据包
 * 
 * 处理网络接口接收到的所有数据包，根据协议类型分发到不同的处理函数。
 * 通常作为网络接口的回调函数使用。
 * 
 * @param src_ip 发送方IP地址
 * @param protocol 协议类型（控制消息或数据消息）
 * @param data 数据包内容
 * @param data_len 数据包长度
 * @return 成功返回0，失败返回负值
 */
extern int aodv_handle_rx_packet(uint32_t src_ip, uint8_t protocol, const void *data, size_t data_len);

/**
 * @brief 处理接收到的AODV控制消息
 * 
 * 解析并分发处理AODV控制消息（RREQ、RREP、RERR），根据消息类型调用对应的处理函数。
 * 
 * @param src_ip 发送方IP地址
 * @param data 消息内容
 * @param data_len 消息长度
 * @return 成功返回0，失败返回负值
 */
extern int aodv_handle_control_message(uint32_t src_ip, const void *data, size_t data_len);

/**
 * @defgroup 路由表管理 路由表管理函数
 * @brief 用于管理AODV协议中的路由表操作
 * @{
 */

/**
 * @brief 向路由表添加新条目
 * 
 * 添加新的路由表项到路由表中。如果目标已存在，则根据序列号和跳数决定是否更新。
 * 
 * @param entry 路由表项结构体指针
 * @return 成功返回0，失败返回负值
 */
extern int route_table_add(route_table_entry_t *entry);

/**
 * @brief 更新路由表中的条目
 * 
 * 更新路由表中已存在的条目，通常用于更新路由的新鲜度或修复路由。
 * 
 * @param entry 更新后的路由表项结构体指针
 * @return 成功返回0，失败返回负值
 */
extern int route_table_update(route_table_entry_t *entry);

/**
 * @brief 在路由表中查找指定目标的条目
 * 
 * 根据目标IP地址在路由表中查找对应的路由表项。
 * 
 * @param dest_ip 目标IP地址
 * @return 找到返回路由表项指针，未找到返回NULL
 */
extern route_table_entry_t *route_table_find(uint32_t dest_ip);

/**
 * @brief 从路由表中删除指定目标的条目
 * 
 * 完全删除路由表中指定目标IP的路由条目。
 * 
 * @param dest_ip 目标IP地址
 * @return 成功返回0，失败返回负值
 */
extern int route_table_delete(uint32_t dest_ip);

/**
 * @brief 将指定目标的路由标记为无效
 * 
 * 将路由表中指定目标IP的路由标记为无效，但不删除，以便后续可能的修复。
 * 
 * @param dest_ip 目标IP地址
 */
extern void route_table_invalidate(uint32_t dest_ip);

/** @} */ // 路由表管理函数组结束

/**
 * @defgroup 邻居表管理 邻居表管理函数
 * @brief 用于管理AODV协议中的邻居节点信息
 * @{
 */

/**
 * @brief 向邻居表添加新条目
 * 
 * 添加新的邻居节点信息到邻居表中。
 * 
 * @param entry 邻居表项结构体指针
 * @return 成功返回0，失败返回负值
 */
extern int neighbor_table_add(neighbor_table_entry_t *entry);

/**
 * @brief 更新邻居表中的条目
 * 
 * 更新邻居表中指定IP地址的条目状态和时间戳。
 * 
 * @param neighbor_ip 邻居节点IP地址
 * @return 成功返回0，失败返回负值
 */
extern int neighbor_table_update(uint32_t neighbor_ip);

/**
 * @brief 在邻居表中查找指定IP的条目
 * 
 * 根据IP地址在邻居表中查找对应的邻居节点信息。
 * 
 * @param neighbor_ip 邻居节点IP地址
 * @return 找到返回邻居表项指针，未找到返回NULL
 */
extern neighbor_table_entry_t *neighbor_table_find(uint32_t neighbor_ip);

/**
 * @brief 从邻居表中删除指定IP的条目
 * 
 * 完全删除邻居表中指定IP地址的邻居条目。
 * 
 * @param neighbor_ip 邻居节点IP地址
 * @return 成功返回0，失败返回负值
 */
extern int neighbor_table_delete(uint32_t neighbor_ip);

/**
 * @brief 将指定IP的邻居标记为不可达
 * 
 * 将邻居表中指定IP地址的邻居状态标记为不可达(DEAD)。
 * 
 * @param neighbor_ip 邻居节点IP地址
 */
extern void neighbor_table_mark_dead(uint32_t neighbor_ip);

/** @} */ // 邻居表管理函数组结束

/**
 * @defgroup 路由发现 路由发现函数
 * @brief 实现AODV协议的路由发现和维护机制
 * @{
 */

/**
 * @brief 发起路由发现过程
 * 
 * 当需要向未知路由的目标发送数据时，调用此函数发起路由发现过程，
 * 生成并广播RREQ消息。
 * 
 * @param dest_ip 目标IP地址
 * @return 成功返回0，失败返回负值
 */
extern int initiate_route_discovery(uint32_t dest_ip);

/**
 * @brief 处理接收到的RREQ消息
 * 
 * 处理接收到的路由请求消息，包括重复检测、反向路由建立、
 * 路由回复生成或请求转发等操作。
 * 
 * @param src_ip 发送RREQ的节点IP地址
 * @param rreq RREQ消息结构体指针
 * @return 成功返回0，失败返回负值
 */
extern int handle_rreq_message(uint32_t src_ip, rreq_message_t *rreq);

/**
 * @brief 处理接收到的RREP消息
 * 
 * 处理接收到的路由回复消息，包括正向路由建立、路由更新、
 * 消息转发以及缓存数据的发送等操作。
 * 
 * @param src_ip 发送RREP的节点IP地址
 * @param rrep RREP消息结构体指针
 * @return 成功返回0，失败返回负值
 */
extern int handle_rrep_message(uint32_t src_ip, rrep_message_t *rrep);

/**
 * @brief 处理接收到的RERR消息
 * 
 * 处理接收到的路由错误消息，包括路由失效处理、
 * 路由表更新和错误消息的适当转发等操作。
 * 
 * @param src_ip 发送RERR的节点IP地址
 * @param rerr RERR消息结构体指针
 * @return 成功返回0，失败返回负值
 */
extern int handle_rerr_message(uint32_t src_ip, rerr_message_t *rerr);

/** @} */ // 路由发现函数组结束

/**
 * @defgroup 定时器管理 定时器管理函数
 * @brief 实现AODV协议的定时器机制
 * @{
 */

/**
 * @brief 创建新的定时器
 * 
 * 创建指定类型和超时时间的定时器。
 * 
 * @param type 定时器类型
 * @param timeout 超时时间（毫秒）
 * @param data 关联的数据指针，用于超时处理
 * @return 成功返回定时器ID，失败返回负值
 */
extern int timer_create(timer_type_t type, uint32_t timeout, void *data);

/**
 * @brief 启动指定的定时器
 * 
 * 启动或重启指定ID的定时器。
 * 
 * @param timer_id 定时器ID
 * @return 成功返回0，失败返回负值
 */
extern int timer_start(int timer_id);

/**
 * @brief 停止指定的定时器
 * 
 * 停止指定ID的定时器，但不释放资源。
 * 
 * @param timer_id 定时器ID
 * @return 成功返回0，失败返回负值
 */
extern int timer_stop(int timer_id);

/**
 * @brief 重启定时器并更新超时时间
 * 
 * 重启指定ID的定时器并设置新的超时时间。
 * 
 * @param timer_id 定时器ID
 * @param new_timeout 新的超时时间（毫秒）
 * @return 成功返回0，失败返回负值
 */
extern int timer_restart(int timer_id, uint32_t new_timeout);

/**
 * @brief 处理所有活动定时器
 * 
 * 检查并处理所有活动定时器，对已超时的定时器执行相应的处理函数。
 * 通常在主循环中周期性调用。
 */
extern void process_timers(void);

/** @} */ // 定时器管理函数组结束

/**
 * @defgroup 邻居维护 邻居发现和维护函数
 * @brief 实现AODV协议的邻居发现和链路维护机制
 * @{
 */

/**
 * @brief 发送HELLO消息
 * 
 * 生成并广播HELLO消息，用于邻居发现和链路状态维护。
 * HELLO消息是AODV中维护网络拓扑动态性的关键机制。
 */
extern void send_hello_message(void);

/**
 * @brief 检查所有邻居状态
 * 
 * 检查邻居表中所有邻居的状态，根据最后收到HELLO消息的时间判断是否失效。
 */
extern void check_neighbor_status(void);

/** @} */ // 邻居维护函数组结束

/**
 * @brief 处理链路故障
 * 
 * 当检测到与某个邻居节点的链路发生故障时，调用此函数处理相关路由。
 * 会生成RERR消息通知网络其他节点。
 * 
 * @param neighbor_ip 发生链路故障的邻居节点IP地址
 */
extern void handle_link_failure(uint32_t neighbor_ip);

/**
 * @brief 获取当前时间（毫秒）
 * 
 * 返回系统当前时间的毫秒值，用于定时器和超时处理。
 * 
 * @return 当前时间（毫秒）
 */
extern uint32_t get_current_time(void);

/**
 * @defgroup 配置管理 配置参数访问函数
 * @brief 用于访问和修改AODV协议的配置参数
 * @{
 */

/**
 * @brief 设置AODV配置参数
 * 
 * 设置AODV协议的各种配置参数，这些参数会影响协议的性能和行为。
 * 
 * @param config 包含新配置参数的结构体指针
 */
extern void aodv_set_config(const aodv_config_t *config);

/**
 * @brief 获取当前AODV配置参数
 * 
 * 获取当前AODV协议使用的配置参数。
 * 
 * @return 当前配置参数结构体指针
 */
extern const aodv_config_t *aodv_get_config(void);

/** @} */ // 配置管理函数组结束

/**
 * @defgroup 调试功能 调试和统计信息
 * @brief 用于调试和监控AODV协议运行状态的函数
 * @{
 */

/**
 * @brief 打印AODV协议统计信息
 * 
 * 打印AODV协议的运行统计信息，如消息数量、路由发现次数等。
 */
extern void aodv_print_stats(void);

/**
 * @brief 打印当前路由表
 * 
 * 打印路由表中的所有路由条目详细信息。
 */
extern void aodv_print_route_table(void);

/**
 * @brief 打印当前邻居表
 * 
 * 打印邻居表中的所有邻居条目详细信息。
 */
extern void aodv_print_neighbor_table(void);

/** @} */ // 调试功能函数组结束

#endif /* AODV_H */